//AS3///////////////////////////////////////////////////////////////////////////
// 
// Copyright(c) 2010 180heartbeats. All rights reserved.
// Please read this carefully before using the source code.
// 
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions are
// met:
// 
// * Redistributions of source code must retain the above copyright notice, 
//   this list of conditions and the following disclaimer.
// 
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the distribution.
// 
// * Neither the name of 180heartbeats nor the names of its 
//   contributors may be used to endorse or promote products derived from 
//   this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////

package com.heartbeats.lab.wiibalanceboard.view
{

import flash.display.Stage;
import flash.events.DataEvent;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.geom.Point;
import flash.net.XMLSocket;
import flash.utils.clearTimeout;
import flash.utils.setTimeout;

import heartbeats.lab.wiibalanceboard.view.CompositeView;
import heartbeats.lab.wiibalanceboard.controllers.IWiiBalanceBoardController;

/**
 * Application entry point for Wii Balance Board.
 * 
 * @langversion ActionScript 3.0
 * @playerversion Flash 9.0
 * 
 * @author Szymon P. Peplinski
 */

public dynamic class WiiBalanceBoard extends CompositeView
{
	protected var _xmlSocket : XMLSocket;
	protected var _timeoutInterval : int;
	protected var _data : Array;
	protected var _point : Point = new Point ();
	
	private const _xmlSocketHost : String = "127.0.0.1";
	private const _xmlSocketPort : int = 19028;
	
	public function WiiBalanceBoard ( aModel : Object, aController : IWiiBalanceBoardController )
	{
		super ( aModel, aController );
	
		this._wiiServerConnect ();
	}

	protected function _wiiServerConnect () : void
	{
		this._xmlSocket = new XMLSocket ();
		this._configureListeners ( this._xmlSocket );
		this._xmlSocketConnect ();
	}
	
	protected function _dataHandler ( event : DataEvent ) : void 
	{
		this._data = event.data.split ( ";" );
		
		this._point.x = parseFloat ( this._data [ 0 ] );
		this._point.y = parseFloat ( this._data [ 1 ] );
		
		if ( isNaN ( this._point.x ) )
		{
			this._point.x = 0;
		}
		
		if ( isNaN ( this._point.y ) )
		{
			this._point.y = 0;
		}
		
		this._point.x = this._point.x * Stage.stageWidth;
		this._point.y = this._point.y * Stage.stageHeight;
		
		this.controller.position ( this._point );
	}

	private function _configureListeners ( dispatcher : IEventDispatcher ) : void 
	{
		dispatcher.addEventListener ( Event.CLOSE, this._closeHandler );
		dispatcher.addEventListener ( Event.CONNECT, this._connectHandler );
		dispatcher.addEventListener ( DataEvent.DATA, this._dataHandler );
		dispatcher.addEventListener ( IOErrorEvent.IO_ERROR, this._ioErrorHandler );
		dispatcher.addEventListener ( SecurityErrorEvent.SECURITY_ERROR, this._securityErrorHandler );
	}

	private function _xmlSocketConnect () : void
	{
		clearTimeout ( this._timeoutInterval );
	
		if ( this.model.isConnected == false )
		{
			this._xmlSocket.connect ( this._xmlSocketHost, this._xmlSocketPort );
			this._timeoutInterval = setTimeout ( this._xmlSocketConnect, 1000 );
		}
	}
	
	private function _closeHandler ( event : Event ) : void 
	{
		trace ( event );
		this.controller.disconnected ();
		this._xmlSocketConnect ();
	}

	private function _connectHandler ( event : Event ) : void 
	{
		trace ( event );
		this.controller.connected ();
		clearTimeout ( this._timeoutInterval );
	}

	private function _ioErrorHandler ( event : IOErrorEvent ) : void 
	{
		trace ( event );
		this._xmlSocketConnect ();
	}

	private function _securityErrorHandler ( event : SecurityErrorEvent ) : void 
	{
		trace ( event );
		this._xmlSocketConnect ();
	}
}